package com.mallcai.bigdata.ladon.dpl.mapper.dashboard.provider;

import com.mallcai.bigdata.ladon.dpl.entity.dashboard.SqlRunLogStatic;
import com.mallcai.bigdata.ladon.dpl.mapper.BaseSqlProvider;
import com.mallcai.bigdata.ladon.dpl.mapper.report.provider.ReportSqlProvider;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.util.Assert;

import java.util.*;

/**
 * @author gst
 * @date 2019-12-30 20:36
 */
public class SqlRunLogStaticSqlProvider extends BaseSqlProvider<SqlRunLogStatic> {

    public static final String TB_SQL_RUN_LOG_STATIC = "r_sql_run_log_statics";

    @Override
    public String getTableName() {
        return TB_SQL_RUN_LOG_STATIC;
    }

    @Override
    public Map<String, String> getInsertColumns() {
        Map<String, String> map = new LinkedHashMap<>();
        map.put("code", "#{code}");
        map.put("fail_count", "#{failCount}");
        map.put("total_count", "#{totalCount}");
        map.put("max_time", "#{maxTime}");
        map.put("min_time", "#{minTime}");
        map.put("avg_time", "#{avgTime}");
        map.put("run_date", "#{runDate}");

        return map;
    }

    @Override
    public Map<String, String> getUpdateColumns() {
        Map<String, String> map = new LinkedHashMap<>();
        map.put("code", "code");
        map.put("failCount", "fail_count");
        map.put("totalCount", "total_count");
        map.put("maxTime", "max_time");
        map.put("minTime", "min_time");
        map.put("avgTime", "avg_time");
        map.put("runDate", "run_date");
        return map;
    }

    public String getByParams(Map<String, Object> map) {
        Map<String, Object> params = getParams(map);

        StringBuilder sb = getStringBuilderByParams(params);

        if (params.containsKey("codes") && params.get("codes") != null) {
            List<String> codeList = (List<String>) params.get("codes");
            StringJoiner sj = new StringJoiner(",", "(", ")");
            sj.add("'useless'");
            for (String code : codeList) {
                sj.add("'" + code + "'");
            }
            sb.append(" AND tb_static.code in " + sj.toString());
        }
        return new SQL() {
            {
                SELECT("tb_static.code,tb_static.total_count totalCount,tb_static.avg_time avgTime,tb_static.run_date runDate,tb_report.name name");
                FROM(getTableName() + " AS tb_static ");
                LEFT_OUTER_JOIN(ReportSqlProvider.TB_REPORT + " AS tb_report on tb_report.code=tb_static.code");
                WHERE(sb.toString());
                ORDER_BY("tb_static.run_date ASC");
            }
        }.toString();
    }

    /**
     * 按照报表查询top10访问次数报表
     */
    public String getTopCount(Map<String, Object> map) {
        Map<String, Object> params = getParams(map);

        StringBuilder sb = getStringBuilderByParams(params);
        return new SQL() {
            {
                SELECT("SUM(tb_static.total_count) totalCount,tb_static.run_date runDate,tb_report.name name");
                FROM(getTableName() + " AS tb_static ");
                LEFT_OUTER_JOIN(ReportSqlProvider.TB_REPORT + " AS tb_report on tb_report.code=tb_static.code");
                WHERE(sb.toString());
                GROUP_BY("tb_static.code");
                ORDER_BY("totalCount DESC LIMIT 10");
            }
        }.toString();
    }

    /**
     * 按照报表查询top10平均访问时间报表
     */
    public String getTopAvgTime(Map<String, Object> map) {
        Map<String, Object> params = getParams(map);

        StringBuilder sb = getStringBuilderByParams(params);
        return new SQL() {
            {
                SELECT("SUM(tb_static.avg_time*tb_static.total_count)/SUM(tb_static.total_count) avgTime,tb_static.run_date runDate,tb_report.name name");
                FROM(getTableName() + " AS tb_static ");
                LEFT_OUTER_JOIN(ReportSqlProvider.TB_REPORT + " AS tb_report on tb_report.code=tb_static.code");
                WHERE(sb.toString());
                GROUP_BY("tb_static.code");
                ORDER_BY("avgTime DESC LIMIT 10");
            }
        }.toString();
    }

    /**
     * 按照时间获取当日全部报表请求次数
     */
    public String getAllReportCountDataByDate(Map<String, Object> map) {
        Map<String, Object> params = getParams(map);

        StringBuilder sb = getStringBuilderByParams(params);
        return new SQL() {
            {
                SELECT("SUM(tb_static.total_count) totalCount,tb_static.run_date runDate,'全部' name");
                FROM(getTableName() + " AS tb_static ");
                LEFT_OUTER_JOIN(ReportSqlProvider.TB_REPORT + " AS tb_report on tb_report.code=tb_static.code");
                WHERE(sb.toString());
                GROUP_BY("tb_static.run_date");
                ORDER_BY("tb_static.run_date ASC");
            }
        }.toString();
    }

    /**
     * 按照时间获取全部当日的平均访问时间
     */
    public String getAllReportAvgTimeDataByDate(Map<String, Object> map) {
        Map<String, Object> params = getParams(map);

        StringBuilder sb = getStringBuilderByParams(params);
        return new SQL() {
            {
                SELECT("SUM(tb_static.total_count*tb_static.avg_time)/SUM(tb_static.total_count) avgTime,tb_static.run_date runDate,'全部' name");
                FROM(getTableName() + " AS tb_static ");
                LEFT_OUTER_JOIN(ReportSqlProvider.TB_REPORT + " AS tb_report on tb_report.code=tb_static.code");
                WHERE(sb.toString());
                GROUP_BY("tb_static.run_date");
                ORDER_BY("tb_static.run_date ASC");
            }
        }.toString();
    }

    private StringBuilder getStringBuilderByParams(Map<String, Object> params) {
        StringBuilder sb = new StringBuilder();
        sb.append("tb_static.archive = 0");

        if (params.containsKey("start") && params.get("start") != null) {
            String start = (String) params.get("start");
            sb.append(" AND tb_static.run_date >= '" + start + "'");
        }
        if (params.containsKey("end") && params.get("end") != null) {
            String end = (String) params.get("end");
            sb.append(" AND tb_static.run_date <= '" + end + "'");
        }
        return sb;
    }

    public String mergeInsert(Map<String, Object> map) {
        Map<String, Object> params = getParams(map);
        List<SqlRunLogStatic> list = (List<SqlRunLogStatic>) params.getOrDefault("list", new ArrayList<>());
        List<String> valueList = new ArrayList<>();
        for (SqlRunLogStatic sqlRunLogStatic : list) {
            StringJoiner sj = new StringJoiner(",", "(", ")");
            sj.add(String.valueOf(sqlRunLogStatic.getId()));
            sj.add("'" + sqlRunLogStatic.getCode() + "'");
            sj.add(String.valueOf(sqlRunLogStatic.getFailCount()));
            sj.add(String.valueOf(sqlRunLogStatic.getTotalCount()));
            sj.add(String.valueOf(sqlRunLogStatic.getMaxTime()));
            sj.add(String.valueOf(sqlRunLogStatic.getMinTime()));
            sj.add(String.valueOf(sqlRunLogStatic.getAvgTime()));
            sj.add("'" + String.valueOf(sqlRunLogStatic.getRunDate()) + "'");
            sj.add("unix_timestamp(now())");
            sj.add("-1");
            valueList.add(sj.toString());
        }
        StringJoiner sj = new StringJoiner(",");
        for (String value : valueList) {
            sj.add(value);
        }
        return "insert into " + getTableName() + " (id,code,fail_count,total_count,max_time,min_time,avg_time,run_date,created,created_by) values " + sj.toString();
    }
}
